package plus;

public class S_Record extends Solution {

	private TS_Record sym;
	private Type[] params;

	public S_Record(TS_Record ts_Record, Type[] actuals) {
		this.sym = ts_Record;
		this.params = actuals;
	}
	private S_Record checkSym(Solution _that) {
		S_Record that = (S_Record) _that;
		if (this.sym != that.sym) Type.mismatch(this.sym.toString(), that.sym.toString());
		return that;
	}
	@Override void conform_to(Solution that, Gamma gamma) { Type.conform(params, checkSym(that).params, gamma); }
	@Override boolean canConform(Solution that, Hypo h) {
		S_Record s = (S_Record) that;
		if (sym != s.sym) return false;
		return Type.canConform(params, s.params, h);
	}
	@Override public void unify_with(Solution that) { Type.unify(params, checkSym(that).params); }
	@Override Type subst(Type[] actuals) {
		//System.out.println("instatiating record "+sym);
		return Type.fresh(new S_Record(sym, Type.subst(params, actuals)));
	}
	@Override Solution copy() { return new S_Record(sym, Type.fresh_vars(params.length)); }
	@Override boolean isNullable() { return sym.isNullable(); }
	public Type typeOfField(String name) { return sym.typeOfField(name, params); }
	public int indexOfField(String name) { return sym.struct.indexOfField(name); }
	public String toString() {
		if (null == params || params.length == 0) return sym.toString();
		StringBuilder sb = new StringBuilder();
		for (Type p:params) {
			sb.append(", ");
			sb.append(p.toString());
		}
		return sym.toString() + "<" + sb.substring(2) + ">";
	}
}
